package com.jyx.search.service;

import com.jyx.framework.domain.course.CoursePub;
import com.jyx.framework.domain.course.TeachplanMediaPub;
import com.jyx.framework.domain.search.CourseSearchParam;
import com.jyx.framework.model.response.CommonCode;
import com.jyx.framework.model.response.QueryResponseResult;
import com.jyx.framework.model.response.QueryResult;
import org.apache.commons.lang3.StringUtils;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class EsCourseService {
    private static final Logger LOGGER = LoggerFactory.getLogger(EsCourseService.class);

    @Value("${jieyouxiang.elasticsearch.course.index}")
    private String es_index;
    @Value("${jieyouxiang.elasticsearch.course.media.index}")
    private String es_media_index;
    @Value("${jieyouxiang.elasticsearch.course.sourse_field}")
    private String source_field;
    @Value("${jieyouxiang.elasticsearch.course.media.sourse_field}")
    private String media_sourse_field;
    @Autowired
    RestHighLevelClient restHighLevelClient;

    /**
     * 初始化搜索课程
     * @param page
     * @param size
     * @param courseSearchParam
     * @return
     */
    public QueryResponseResult<CoursePub> list(int page, int size, CourseSearchParam courseSearchParam){
        //设置索引
        SearchRequest searchRequest = new SearchRequest(es_index);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //source源字段过滤
        String[] source_fields = source_field.split(",");
        searchSourceBuilder.fetchSource(source_fields, new String[]{});

        //关键字匹配
        if(StringUtils.isNotEmpty(courseSearchParam.getKeyword())) {
            MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(courseSearchParam.getKeyword(),"name",
                    "teachplan","description");
            multiMatchQueryBuilder.minimumShouldMatch("70%");
            multiMatchQueryBuilder.field("name",10);
            boolQueryBuilder.must(multiMatchQueryBuilder);

        }
        //过滤
        if(StringUtils.isNotEmpty(courseSearchParam.getMt())){
            boolQueryBuilder.filter(QueryBuilders.termQuery("mt",courseSearchParam.getMt()));
        }
        if(StringUtils.isNotEmpty(courseSearchParam.getSt())){
            boolQueryBuilder.filter(QueryBuilders.termQuery("st",courseSearchParam.getSt()));
        }
        if(StringUtils.isNotEmpty(courseSearchParam.getGrade())){
            boolQueryBuilder.filter(QueryBuilders.termQuery("grade",courseSearchParam.getGrade()));
        }
        //布尔查询
        searchSourceBuilder.query(boolQueryBuilder);
        //分页
        if(page<=0){
            page = 1;
        }
        if(size<=0){
            size = 12;
        }
        int start = (page-1)*size;
        searchSourceBuilder.from(start);
        searchSourceBuilder.size(size);

        //高亮设置
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<font class='eslight'>");
        highlightBuilder.postTags("</font>");
        highlightBuilder.fields().add(new HighlightBuilder.Field("name"));
        searchSourceBuilder.highlighter(highlightBuilder);
        //请求搜索
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = null;
        try{
            searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        }catch (IOException e){
            e.printStackTrace();
            LOGGER.error("jieyouxiang search error..{}",e.getMessage());
            return new QueryResponseResult<>(CommonCode.SUCCESS,new QueryResult<CoursePub>());
        }
        //结果集处理
        SearchHits hits = searchResponse.getHits();
        TotalHits totalHits = hits.getTotalHits();
        //记录总数
        long hitsSize = totalHits.value;
        //System.out.println(hitsSize);
        SearchHit[] searchHits = hits.getHits();

        //数据列表
        List<CoursePub> coursePubList = new ArrayList<>();
        for(SearchHit searchHit:searchHits){
            //补充coursepub
            CoursePub coursePub = new CoursePub();
            //取出source
            Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
            //取出字段
            String name = (String) sourceAsMap.get("name");
            String charge = (String) sourceAsMap.get("charge");
            String pic = (String) sourceAsMap.get("pic");
            String id = (String) sourceAsMap.get("id");
            Float price = null;
            try{
                if(sourceAsMap.get("price")!=null){
                    price = ((Double) sourceAsMap.get("price")).floatValue();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
            Float price_old = null;
            try{
                if(sourceAsMap.get("price_old")!=null){
                    price_old = ((Double) sourceAsMap.get(price_old)).floatValue();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
            coursePub.setName(name);
            coursePub.setPic(pic);
            coursePub.setCharge(charge);
            coursePub.setPrice(price);
            coursePub.setPrice_old(price_old);
            coursePub.setId(id);
            coursePubList.add(coursePub);
        }
        //封装返回结果
        QueryResult<CoursePub> queryResult = new QueryResult<>();
        queryResult.setTotal(hitsSize);
        queryResult.setList(coursePubList);
        return new QueryResponseResult<>(CommonCode.SUCCESS, queryResult);
    }

    /**
     * 根据id搜索课程信息
     * @param id
     * @return
     */
    public Map<String, CoursePub> getAll(String id) {
        SearchRequest searchRequest = new SearchRequest(es_index);

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //设置查询条件
        searchSourceBuilder.query(QueryBuilders.termsQuery("id",id));
        //查询所有字段  不设置源字段---下面这个是设置匹配字段
        //searchSourceBuilder.fetchSource(new String[]{"name","grade","charge","pic"},new String[]{});
        //
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = null;
        Map<String, CoursePub> coursePubMap = new HashMap<>();
        try{
            searchResponse = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
            SearchHits hits = searchResponse.getHits();
            SearchHit[] searchHits = hits.getHits();
            for (SearchHit searchHit : searchHits) {
                //String courseId = searchHit.getId();
                Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
                /**
                 * id  name  grade charge pic description teachplan
                 */
                String courseId = (String) sourceAsMap.get("id");
                String name = (String) sourceAsMap.get("name");
                String grade = (String) sourceAsMap.get("grade");
                String charge = (String) sourceAsMap.get("charge");
                String pic = (String) sourceAsMap.get("pic");
                String description = (String) sourceAsMap.get("description");
                String teachplan = (String) sourceAsMap.get("teachplan");
                CoursePub coursePub = new CoursePub();
                coursePub.setId(courseId);
                coursePub.setName(name);
                coursePub.setTeachplan(teachplan);
                coursePub.setGrade(grade);
                coursePub.setCharge(charge);
                coursePub.setPic(pic);
                coursePub.setDescription(description);
                coursePubMap.put(courseId,coursePub);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return coursePubMap;
    }

    /**
     * es搜索媒体资料
     * @param teachplanIds
     * @return
     */
    public QueryResponseResult<TeachplanMediaPub> getMedia(String[] teachplanIds) {
        SearchRequest searchRequest = new SearchRequest(es_media_index);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.termsQuery("teachplan_id", teachplanIds));

        String[] sourse_fields = media_sourse_field.split(",");
        searchSourceBuilder.fetchSource(sourse_fields, new String[]{});
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = null;
        try {
            searchResponse = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
        }catch (Exception e){
            e.printStackTrace();
        }
        SearchHits searchHits = searchResponse.getHits();
        SearchHit[] hits = searchHits.getHits();
        List<TeachplanMediaPub> mediaPubList = new ArrayList<>();
        for (SearchHit searchHit : hits){
            TeachplanMediaPub teachplanMediaPub = new TeachplanMediaPub();
            Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
            //courseid    media_id   media_url   teachplan_id   media_fileoriginalname
            String courseid = (String) sourceAsMap.get("courseid");
            String media_id = (String) sourceAsMap.get("media_id");
            String media_url = (String) sourceAsMap.get("media_url");
            String teachplan_id = (String) sourceAsMap.get("teachplan_id");
            String media_fileoriginalname = (String) sourceAsMap.get("media_fileoriginalname");
            teachplanMediaPub.setCourseId(courseid);
            teachplanMediaPub.setMediaId(media_id);
            teachplanMediaPub.setMediaUrl(media_url);
            teachplanMediaPub.setTeachplanId(teachplan_id);
            teachplanMediaPub.setMediaFileOriginalName(media_fileoriginalname);
            mediaPubList.add(teachplanMediaPub);
        }

        QueryResult<TeachplanMediaPub> queryResult = new QueryResult<>();
        queryResult.setList(mediaPubList);
        queryResult.setTotal(mediaPubList.size());
        return new QueryResponseResult<>(CommonCode.SUCCESS, queryResult);
    }
}
